using System;
using System.Text;

namespace csammisrun.OscarLib
{
	/// <summary>
	/// Encapsulates an AIM/ICQ user information block
	/// </summary>
	public class UserInfo
	{
    private string _screenname = "";
    public ushort _warninglevel = 0x0000;
    public UserClass _class = UserClass.Unconfirmed;
    private uint _createtime = 0, _signontime = 0, _registertime = 0, _onlinetime = 0;
    private ushort _idletime = 0;
    private uint _icquserstatus = 0, _icqexternalip = 0;
    private UserDCInfo _dc = null;
    private Capabilities _caps = Capabilities.None;
    private IconInfo _iconinfo = null;
    private string _availablemsg = "";
    private Encoding _availableencoding = Encoding.ASCII;

		/// <summary>
		/// Gets the user's screenname
		/// </summary>
    public string ScreenName
    {
      get { return _screenname; }
      set { _screenname = value; }
    }

		/// <summary>
		/// Gets the user's current warning level
		/// </summary>
    public ushort WarningLevel
    {
      get { return _warninglevel; }
      internal set { _warninglevel = value; }
    }

		/// <summary>
		/// Gets the user's <see cref="UserClass"/>
		/// </summary>
    public UserClass Class
    {
      get { return _class; }
      internal set { _class = value; }
    }

		/// <summary>
		/// Gets the user's account creation time, in UNIX time_t format
		/// </summary>
    public uint CreateTime
    {
      get { return _createtime; }
      internal set { _createtime = value; }
    }

		/// <summary>
		/// Gets the user's signon time, in UNIX time_t format
		/// </summary>
    public uint SignonTime
    {
      get { return _signontime; }
      internal set { _signontime = value; }
    }

		/// <summary>
		/// Gets the user's idle time, in minutes
		/// </summary>
    public ushort IdleTime
    {
      get { return _idletime; }
      internal set { _idletime = value; }
    }

		/// <summary>
		/// Gets the time when this account was registered ("Member Since"), in UNIX time_t format
		/// </summary>
    public uint RegisterTime
    {
      get { return _registertime; }
      internal set { _registertime = value; }
    }

		/// <summary>
		/// Gets an ICQ user's status
		/// </summary>
    /// <remarks>This property will be empty (0) for an AIM user</remarks>
    public uint ICQUserStatus
    {
      get { return _icquserstatus; }
      internal set { _icquserstatus = value; }
    }

		/// <summary>
		/// Gets an ICQ user's external IP address
		/// </summary>
    /// <remarks>This property will be empty for an AIM user</remarks>
    public uint ExternalIPAddress
    {
      get { return _icqexternalip; }
      internal set { _icqexternalip = value; }
    }

    /// <summary>
    /// Gets an ICQ user's DC (DirectConnect) info
    /// </summary>
    /// <remarks>This property will be <c>null</c> for an AIM user</remarks>
    public UserDCInfo DC
    {
      get { return _dc; }
      internal set { _dc = value; }
    }

		/// <summary>
		/// Gets the remote client's capability list
		/// </summary>
    public Capabilities ClientCapabilities
    {
      get { return _caps; }
      internal set { _caps = value; }
    }

		/// <summary>
		/// Gets the user's online time, in seconds
		/// </summary>
    public uint OnlineTime
    {
      get { return _onlinetime; }
      internal set { _onlinetime = value; }
    }

		/// <summary>
		/// Gets the user's buddy icon information
		/// </summary>
    /// <remarks>This property is <c>null</c> if no icon information has been received</remarks>
    public IconInfo Icon
    {
      get { return _iconinfo; }
      internal set { _iconinfo = value; }
    }

		/// <summary>
		/// Gets the user's "available" message
		/// </summary>
    public string AvailableMessage
    {
      get { return _availablemsg; }
      internal set { _availablemsg = value; }
    }

		/// <summary>
		/// Gets the <see cref="Encoding"/> of the user's "available" message
		/// </summary>
    public Encoding AvailableMessageEncoding
    {
      get { return _availableencoding; }
      internal set { _availableencoding = value; }
    }
	}

  public class UserDCInfo
  {
    public string InternalIP = "";
    public uint InternalPort = 0x00000000;
    public byte DCType = 0x00;
    public ushort DCVersion = 0x0000;
    public uint AuthCookie = 0x00000000;
    public uint WebFrontPort = 0x00000000;
    public uint ClientFutures = 0x00000003; // Always 3?
    public uint LastInfoUpdateTime = 0x00000000;
    public uint LastExtInfoUpdateTime = 0x00000000;
    public uint LastExtStatusUpdateTime = 0x00000000;
    public ushort Unknown = 0x0000;
  }

	/// <summary>
	/// Describes an AOL user's class
	/// </summary>
	public enum UserClass
	{
		/// <summary>
		/// Unconfirmed user
		/// </summary>
		Unconfirmed = 0x0001,
		/// <summary>
		/// AOL adminstrator
		/// </summary>
		Administrator = 0x0002,
		/// <summary>
		/// AOL staff
		/// </summary>
		AOLStaff = 0x0004,
		/// <summary>
		/// Commercial account
		/// </summary>
		Commercial = 0x0008,
		/// <summary>
		/// Non-commercial account
		/// </summary>
		Free = 0x0010,
		/// <summary>
		/// User is away
		/// </summary>
		Away = 0x0020,
		/// <summary>
		/// ICQ user
		/// </summary>
		ICQ = 0x0040,
		/// <summary>
		/// AOL Wireless user
		/// </summary>
		Wireless = 0x0080
	}

	/// <summary>
	/// Describes a request for user information, one block at a time
	/// </summary>
	/// <remarks>The BasicUserInfoRequest members cannot be ORed together. To request more
	/// than one type of information at a time, use the <see cref="UserInfoRequest"/> enumeration
	/// with the <see cref="Session.RequestUserInfo"/> method</remarks>
	public enum BasicUserInfoRequest
	{
		/// <summary>
		/// General information -- the user's profile
		/// </summary>
		GeneralInfo = 0x0001,
		/// <summary>
		/// Online information -- a <see cref="UserInfo"/> block
		/// </summary>
		OnlineInfo = 0x0002,
		/// <summary>
		/// Away message
		/// </summary>
		AwayMessage = 0x0003,
		/// <summary>
		/// Client capabilities
		/// </summary>
		Capabilities = 0x0004
	}

	/// <summary>
	/// Describes a multi-part request for user information
	/// </summary>
	/// <remarks>The UserInfoRequest members can be ORed together</remarks>
	public enum UserInfoRequest
	{
		/// <summary>
		/// User's profile
		/// </summary>
		UserProfile = 0x00000001,
		/// <summary>
		/// User's away message
		/// </summary>
		AwayMessage = 0x00000002,
		/// <summary>
		/// Remote client's capabilities
		/// </summary>
		Capabilities = 0x00000004
	}

	/// <summary>
	/// Encapsulates information about a buddy icon
	/// </summary>
	public class IconInfo
	{
		/// <summary>
		/// The icon's ID
		/// </summary>
		public ushort ID;
    /// <summary>
    /// The type of the hash - usually 0x00 indicating MD5
    /// </summary>
    public byte HashType;
		/// <summary>
		/// The MD5 hash of the icon
		/// </summary>
		public byte[] Hash;
	}

	/// <summary>
	/// Encapsulates the results of a request for user information
	/// </summary>
	public struct UserInfoResponse
	{
		/// <summary>
		/// The user's information structure
		/// </summary>
		public UserInfo Info;
		/// <summary>
		/// The user's profile
		/// </summary>
		public string Profile;
		/// <summary>
		/// The <see cref="System.Text.Encoding"/> of the user's profile string
		/// </summary>
		public Encoding ProfileEncoding;
		/// <summary>
		/// The user's away message
		/// </summary>
		public string AwayMessage;
		/// <summary>
		/// The <see cref="System.Text.Encoding"/> of the user's away message string
		/// </summary>
		public Encoding AwayMessageEncoding;
		/// <summary>
		/// The remote client's capabilities
		/// </summary>
		public Capabilities ClientCapabilities;
	}
}
